package cn.easyplatform.studio.web.editors.project;

import cn.easyplatform.lang.Strings;
import cn.easyplatform.studio.utils.*;
import cn.easyplatform.studio.vos.MediaFileVo;
import cn.easyplatform.studio.vos.UploadHistVo;
import cn.easyplatform.studio.web.editors.ComponentCallback;
import cn.easyplatform.studio.web.editors.version.AllExportEditor;
import cn.easyplatform.studio.web.layout.WorkbenchController;
import cn.easyplatform.studio.web.views.impl.AbstractView;
import org.zkoss.util.resource.Labels;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zul.*;
import sun.misc.BASE64Encoder;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

public class FileExportEditor extends AllExportEditor {
    protected Textbox name;
    protected Combobox mediaType;
    protected Datebox beginDate;
    protected Datebox endDate;
    protected Listbox from;

    private List<MediaFileVo> vos;
    public FileExportEditor(WorkbenchController workbench, String id) {
        super(workbench, id);
    }

    @Override
    protected void dispatch(Event evt) {
        if (evt.getName().equals(Events.ON_CLICK)) {
            Component comp = evt.getTarget();
            if (comp.getId().equals("fileExport_button_query")) {
                List<MediaFileVo> vos = search(name.getValue(), (String) mediaType.getSelectedItem().getValue(), beginDate.getValue(), endDate.getValue());
                allListCheck.setChecked(false);
                pageListCheck.setChecked(false);
                revListCheck.setChecked(false);
                redrawTree(vos);
            } else if (comp.getId().equals("fileExport_image_chooseAllBtn")) {
                select(false);
            } else if (comp.getId().equals("fileExport_image_chooseBtn")) {
                select(true);
            } else if (comp.getId().equals("fileExport_image_removeBtn")) {
                unselect(true);
            } else if (comp.getId().equals("fileExport_image_removeAllBtn")) {
                unselect(false);
            } else if (comp.getId().equals("fileExport_toolbarbutton_export")) {
                export(comp);
            }
        } else if (evt.getName().equals(Events.ON_CHECK)) {
            Checkbox r = (Checkbox) evt.getTarget();
            doCheck(r);
        } else if (evt.getName().equals((Events.ON_DOUBLE_CLICK))) {
            Listitem ti = (Listitem) evt.getTarget();
            MediaFileVo vo = ti.getValue();
            AbstractView.createFileView(new ComponentCallback(name, Labels.getLabel("editor.import.file.info")),
                    vo).doOverlapped();
        }
    }

    @Override
    public void create(Object... args) {
        Idspace is = createPanel(Labels.getLabel("menu.repo.export.file"), "~./images/file.png",
                "~./include/editor/project/fileExport.zul");
        name = (Textbox)is.getFellow("fileExport_textbox_name");
        mediaType = (Combobox)is.getFellow("fileExport_combobox_mediaType");
        beginDate = (Datebox)is.getFellow("fileExport_datebox_beginDate");
        endDate = (Datebox)is.getFellow("fileExport_datebox_endDate");
        from = (Listbox)is.getFellow("fileExport_tree_sources");
        targets = (Listbox)is.getFellow("fileExport_listbox_targets");
        comment = (Textbox) is.getFellow("fileExport_textbox_comment");
        Button searchBtn = (Button)is.getFellow("fileExport_button_query");
        searchBtn.addEventListener(Events.ON_CLICK, this);
        allListCheck = (Checkbox)is.getFellow("fileExport_checkbox_checkAll");
        allListCheck.addEventListener(Events.ON_CHECK, this);
        pageListCheck = (Checkbox)is.getFellow("fileExport_checkbox_checkPage");
        pageListCheck.addEventListener(Events.ON_CHECK, this);
        revListCheck = (Checkbox)is.getFellow("fileExport_checkbox_checkRev");
        revListCheck.addEventListener(Events.ON_CHECK, this);
        is.getFellow("fileExport_image_chooseAllBtn").addEventListener(Events.ON_CLICK, this);
        is.getFellow("fileExport_image_chooseBtn").addEventListener(Events.ON_CLICK, this);
        is.getFellow("fileExport_image_removeBtn").addEventListener(Events.ON_CLICK, this);
        is.getFellow("fileExport_image_removeAllBtn").addEventListener(Events.ON_CLICK, this);
        is.getFellow("fileExport_toolbarbutton_export").addEventListener(Events.ON_CLICK, this);

        FileUtil.mkdirForNoExists(new StudioServiceFileUtils().imgDirPath_stu);
        FileUtil.mkdirForNoExists(new StudioServiceFileUtils().videoDirPath_stu);
        FileUtil.mkdirForNoExists(new StudioServiceFileUtils().audioDirPath_stu);
        FileUtil.mkdirForNoExists(new StudioServiceFileUtils().cssDirPath_stu);
        FileUtil.mkdirForNoExists(new StudioServiceFileUtils().jsDirPath_stu);

        vos = getAllMedia();
        redrawTree(vos);
    }

    protected void redrawTree(List<MediaFileVo> vos) {
        from.getItems().clear();
        if (vos != null) {
            for (MediaFileVo vo: vos) {
                Listitem row = new Listitem();
                row.appendChild(new Listcell(vo.getName()));
                String typeStr = null;
                if (ServiceFileUtil.MediaType.MEDIA_TYPE_IMG.getName().equals(vo.getType())) {
                    typeStr = Labels.getLabel("editor.file.img");
                } else if (ServiceFileUtil.MediaType.MEDIA_TYPE_VIDEO.getName().equals(vo.getType())) {
                    typeStr = Labels.getLabel("editor.file.video");
                } else if (ServiceFileUtil.MediaType.MEDIA_TYPE_AUDIO.getName().equals(vo.getType())) {
                    typeStr = Labels.getLabel("editor.file.audio");
                } else if (ServiceFileUtil.MediaType.MEDIA_TYPE_CSS.getName().equals(vo.getType())) {
                    typeStr = Labels.getLabel("editor.file.css");
                } else if (ServiceFileUtil.MediaType.MEDIA_TYPE_JS.getName().equals(vo.getType())) {
                    typeStr = Labels.getLabel("editor.file.js");
                }
                row.appendChild(new Listcell(typeStr));
                row.appendChild(new Listcell(vo.getSize()));
                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String dateString = format.format(vo.getUpdateDate());
                row.appendChild(new Listcell(dateString));
                row.setValue(vo);
                row.addEventListener(Events.ON_DOUBLE_CLICK, this);

                from.appendChild(row);
            }
        }
    }

    protected void select(boolean selectFlag) {
        for (Listitem sel : from.getItems()) {
            if (selectFlag && !sel.isSelected())
                continue;
            if (sel.getValue() != null) {
                boolean exists = false;
                MediaFileVo s = sel.getValue();
                for (Listitem li : targets.getItems()) {
                    MediaFileVo t = li.getValue();
                    if (s.getName().equals(t.getName()) && s.getType().equals(t.getType())) {
                        exists = true;
                        break;
                    }
                }
                if (!exists) {
                    Listitem li = new Listitem();
                    li.appendChild(new Listcell(s.getName()));
                    String typeStr = null;
                    if (ServiceFileUtil.MediaType.MEDIA_TYPE_IMG.getName().equals(s.getType())) {
                        typeStr = Labels.getLabel("editor.file.img");
                    } else if (ServiceFileUtil.MediaType.MEDIA_TYPE_VIDEO.getName().equals(s.getType())) {
                        typeStr = Labels.getLabel("editor.file.video");
                    } else if (ServiceFileUtil.MediaType.MEDIA_TYPE_AUDIO.getName().equals(s.getType())) {
                        typeStr = Labels.getLabel("editor.file.audio");
                    } else if (ServiceFileUtil.MediaType.MEDIA_TYPE_CSS.getName().equals(s.getType())) {
                        typeStr = Labels.getLabel("editor.file.css");
                    } else if (ServiceFileUtil.MediaType.MEDIA_TYPE_JS.getName().equals(s.getType())) {
                        typeStr = Labels.getLabel("editor.file.js");
                    }
                    li.appendChild(new Listcell(typeStr));
                    li.appendChild(new Listcell(s.getSize()));
                    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    String dateString = format.format(s.getUpdateDate());
                    li.appendChild(new Listcell(dateString));
                    li.setValue(s);
                    targets.appendChild(li);
                }
            }
        }
    }

    protected void unselect(boolean selectedFlag) {
        if (selectedFlag) {
            if (targets.getSelectedCount() > 0) {
                List<Listitem> items = new ArrayList<Listitem>();
                for (Listitem li : targets.getSelectedItems())
                    items.add(li);
                for (Listitem li : items)
                    li.detach();
            }
        } else
            targets.getItems().clear();
    }

    protected void doCheck(Checkbox cbx) {
        if (cbx.getValue().equals("1") || cbx.getValue().equals("3")) {
            Iterator<Component> itr = from.queryAll("Listitem").iterator();
            while (itr.hasNext()) {
                Listitem ti = (Listitem) itr.next();
                if (ti.getValue() != null) {

                    if (cbx.getValue().equals("1")) {
                        ti.setSelected(cbx.isChecked());
                    }
                    else {
                        ti.setSelected(!ti.isSelected());
                    }
                }
            }
        } else {
            int pos = from.getPagingChild().getActivePage() * from.getPagingChild().getPageSize();
            int to = (from.getPagingChild().getActivePage() + 1) * from.getPagingChild().getPageSize();
            List<Listitem> data = new ArrayList<>(from.getItems());
            for (; pos < to; pos++) {
                if (data.size()>pos) {
                    Listitem ti = data.get(pos);
                    ti.setSelected(cbx.isChecked());
                }
            }
        }
    }

    //导出
    protected void export(Component btn) {
        if (targets.getItems().isEmpty()) {
            WebUtils.showError(Labels.getLabel("editor.export.empty"));
            return;
        }
        if (Strings.isBlank(comment.getValue())) {
            WebUtils.notEmpty(Labels.getLabel("editor.export.comment"));
            return;
        }
        Clients.clearWrongValue(btn);
        //打包保存
        boolean canExport = true;
        String errorStr = null;
        List<UploadHistVo> vos = new ArrayList<>();
        for (Listitem li : targets.getItems()) {
            MediaFileVo e = li.getValue();
            if (Strings.isBlank(e.getSize()) == false && e.getSize().length() > 2) {
                double size = Double.parseDouble(e.getSize().substring(0,e.getSize().length() - 2));
                if (size > 300.00 && (ServiceFileUtil.MediaType.MEDIA_TYPE_IMG.getName().equals(e.getType()) ||
                        ServiceFileUtil.MediaType.MEDIA_TYPE_AUDIO.getName().equals(e.getType()))) {
                    canExport = false;
                    if (ServiceFileUtil.MediaType.MEDIA_TYPE_IMG.getName().equals(e.getType()))
                        errorStr = Labels.getLabel("editor.file.img.imgUploadTips");
                    else
                        errorStr = Labels.getLabel("editor.file.audio.audioUploadTips");
                    break;
                } else if (size > 1024.00 && (ServiceFileUtil.MediaType.MEDIA_TYPE_CSS.getName().equals(e.getType()) ||
                        ServiceFileUtil.MediaType.MEDIA_TYPE_JS.getName().equals(e.getType())||
                        ServiceFileUtil.MediaType.MEDIA_TYPE_VIDEO.getName().equals(e.getType()))) {
                    canExport = false;
                    if (ServiceFileUtil.MediaType.MEDIA_TYPE_CSS.getName().equals(e.getType()))
                        errorStr = Labels.getLabel("editor.file.css.cssUploadTips");
                    else if (ServiceFileUtil.MediaType.MEDIA_TYPE_JS.getName().equals(e.getType()))
                        errorStr = Labels.getLabel("editor.file.js.jsUploadTips");
                    else
                        errorStr = Labels.getLabel("editor.file.video.videoUploadTips");
                    break;
                }
                UploadHistVo histVo = new UploadHistVo();
                histVo.setFileName(e.getName());
                histVo.setType(e.getType());
                histVo.setContentType(FileUtil.getFileContentType(e.getPath()));
                BASE64Encoder encoder = new BASE64Encoder();
                String contentStr = encoder.encode(FileUtil.getBytes(e.getPath()));
                histVo.setUploadData(contentStr);
                histVo.setCreateDate(new Timestamp(e.getUpdateDate().getTime()));
                vos.add(histVo);
            } else {
                canExport = false;
                break;
            }
        }
        if (canExport == false)
            WebUtils.showError(errorStr);
        else
            StudioUtil.exportFile(vos, comment.getValue());
    }

    private List<MediaFileVo> getAllMedia() {
        List<MediaFileVo> list = FileUtil.getAllFileInDir(new StudioServiceFileUtils().imgDirPath_stu, ServiceFileUtil.MediaType.MEDIA_TYPE_IMG.getName());
        List<MediaFileVo> videoList = FileUtil.getAllFileInDir(new StudioServiceFileUtils().videoDirPath_stu, ServiceFileUtil.MediaType.MEDIA_TYPE_VIDEO.getName());
        if (videoList != null)
            list.addAll(videoList);
        List<MediaFileVo> audioList = FileUtil.getAllFileInDir(new StudioServiceFileUtils().audioDirPath_stu, ServiceFileUtil.MediaType.MEDIA_TYPE_AUDIO.getName());
        if (audioList != null)
            list.addAll(audioList);
        List<MediaFileVo> cssList = FileUtil.getAllFileInDir(new StudioServiceFileUtils().cssDirPath_stu, ServiceFileUtil.MediaType.MEDIA_TYPE_CSS.getName());
        if (cssList != null)
            list.addAll(cssList);
        List<MediaFileVo> jsList = FileUtil.getAllFileInDir(new StudioServiceFileUtils().jsDirPath_stu, ServiceFileUtil.MediaType.MEDIA_TYPE_JS.getName());
        if (jsList != null)
            list.addAll(jsList);
        return list;
    }

    private List<MediaFileVo> search(String name, String type, Date startDate, Date endDate) {
        List<MediaFileVo> list = new ArrayList<>();
        for (MediaFileVo mediaFileVo: vos) {
            if (Strings.isBlank(name) == false && mediaFileVo.getName().contains(name) == false)
                continue;
            if (Strings.isBlank(type) == false && mediaFileVo.getType().equals(type) == false)
                continue;
            if ((startDate != null && mediaFileVo.getUpdateDate().compareTo(startDate) < 0) ||
                    (endDate != null && mediaFileVo.getUpdateDate().compareTo(endDate) > 0))
                continue;
            list.add(mediaFileVo);
        }
        return list;
    }
}
